<template>
  <canvas ref="bjsCanvas"></canvas>
</template>

<script setup lang="ts">
  import { ref, onMounted, onUnmounted } from 'vue'
  import useInitBabylon from './useInitBabylon'
  import '@babylonjs/loaders'

  import moutainGlb from '@/assets/glb/moutain.glb?url'
  import waterGlb from '@/assets/glb/water.glb?url'
  import treeGlb from '@/assets/glb/tree.glb?url'
  import houseGlb from '@/assets/glb/house.glb?url'
  import {WaterMaterial } from '@babylonjs/materials'
  import { createGround } from './basic/createGround'
  import { HemisphericLight } from '@babylonjs/core/Lights/hemisphericLight'
  import { Color3, Vector2, Vector3 } from '@babylonjs/core/Maths'
  import { MeshBuilder } from '@babylonjs/core/Meshes/meshBuilder'
  import type { Scene } from '@babylonjs/core/scene'
  import { ImportMeshAsync } from '@babylonjs/core/Loading/sceneLoader.js'
  import { StandardMaterial } from '@babylonjs/core/Materials/standardMaterial'
  import { CubeTexture } from '@babylonjs/core/Materials/Textures/cubeTexture'
  import { Texture } from '@babylonjs/core/Materials/Textures/texture'
  const bjsCanvas = ref<HTMLCanvasElement | null>(null)

  const { engine, scene } = useInitBabylon(bjsCanvas)

  const renderParams = async () => {
    // 添加光源
    const light1 = new HemisphericLight(
      'light1',
      new Vector3(40, 40, 80),
      scene.value as Scene
    )
    light1.intensity = 0.7
    // const light2 = new HemisphericLight("light2", new Vector3(50, 50, -80), scene.value as Scene);
    // light2.intensity = 0.3;

    const skybox = MeshBuilder.CreateBox(
      'skyBox',
      { size: 500 },
      scene.value as Scene
    )
    createSky(scene.value as Scene, skybox)
    // createMountain(scene.value as Scene)
    createHouse(scene.value as Scene)
    createTree(scene.value as Scene)
    const ground = createGround(scene.value as Scene)

    createWater(scene.value as Scene, skybox, ground)
    // 启动渲染循环
    engine.value?.runRenderLoop(() => {
      scene.value?.render()
    })
  }

  onMounted(() => {
    renderParams()
  })

  onUnmounted(() => {
    bjsCanvas.value = null
  })

  // 加载树木
  const createTree = (scene: Scene) => {
    const trees = [
      {
        name: 'tree1',
        position: new Vector3(17, 0, -120),
        rotation: new Vector3(0, 0, 0),
        scaling: new Vector3(0.5, 0.5, 0.5),
      },
      {
        name: 'tree2',
        position: new Vector3(50, 0, -120),
        rotation: new Vector3(0, 0, 0),
        scaling: new Vector3(0.8, 0.8, 0.8),
      },
      {
        name: 'tree3',
        position: new Vector3(10, 0, -130),
        rotation: new Vector3(0, 0, 0),
        scaling: new Vector3(0.7, 0.7, 0.7),
      },
    ]
    trees.map((tree) => {
      ImportMeshAsync(treeGlb, scene, {})
        .then((result) => {
          if (result.meshes.length > 0) {
            // 处理加载的网格
            const mesh = result.meshes[0]
            mesh.name = tree.name
            mesh.position = tree.position // 设置位置
            mesh.rotation = tree.rotation // 设置旋转
            mesh.scaling = tree.scaling // 设置缩放
            mesh.freezeWorldMatrix()
          }
        })
        .catch((error) => {
          // 处理加载错误
          console.error('Error loading tree mesh:', error)
        })
    })
  }

  // 加载房屋
  const createHouse = (scene: Scene) => {
    const houses = [
      {
        name: 'house1',
        position: new Vector3(57, 0, -130),
        rotation: new Vector3(0, Math.PI / 6, 0),
        scaling: new Vector3(1.5, 1.5, 1.5),
      },
      {
        name: 'house2',
        position: new Vector3(20, 0, -130),
        rotation: new Vector3(0, Math.PI / 6, 0),
        scaling: new Vector3(1, 1, 1),
      },
      {
        name: 'house3',
        position: new Vector3(15, 0, -130),
        rotation: new Vector3(0, Math.PI / 6, 0),
        scaling: new Vector3(2, 2, 2),
      },
    ]
    houses.map((house) => {
      ImportMeshAsync(houseGlb, scene, {})
        .then((result) => {
          if (result.meshes.length > 0) {
            // 处理加载的网格
            const mesh = result.meshes[0]
            mesh.name = house.name
            mesh.position = house.position // 设置位置
            mesh.rotation = house.rotation // 设置旋转
            mesh.scaling = house.scaling // 设置缩放
            mesh.freezeWorldMatrix()
          }
        })
        .catch(() => {})
    })
  }

  // 生成天空
  const createSky = (scene: Scene, skybox: any) => {
    const skyboxMaterial = new StandardMaterial('skyBox', scene)
    skyboxMaterial.backFaceCulling = false
    skyboxMaterial.reflectionTexture = new CubeTexture(
      '/textures/TropicalSunnyDay',
      scene
    )
    skyboxMaterial.reflectionTexture.coordinatesMode = Texture.SKYBOX_MODE
    skyboxMaterial.diffuseColor = new Color3(0, 0, 0)
    skyboxMaterial.specularColor = new Color3(0, 0, 0)
    skyboxMaterial.disableLighting = true
    skybox.material = skyboxMaterial
  }

  // 生成水面
  const createWater = (scene: Scene, skybox: any, ground: any) => {
    ImportMeshAsync(waterGlb, scene, {})
      .then((result) => {
        if (result.meshes.length > 0) {
          const groundMesh = result.meshes[1]
          groundMesh.name = 'waterGround'
          groundMesh.position = new Vector3(20, 0, 50) // 设置位置
          groundMesh.rotation = new Vector3(0, Math.PI / 9, 0) // 设置旋转
          groundMesh.scaling = new Vector3(2.5, 2, 3) // 设置缩放
          groundMesh.position.y = -1
          // const waterMat = MeshBuilder.CreateGround('waterGround', {
          //     width: 100,
          //     height: 100,
          //     subdivisions: 100,
          //     updatable: true,
          // }, scene)
          // waterMat.parent = groundMesh
          const waterMaterial = new WaterMaterial(
            'water',
            scene,
            new Vector2(1024, 1024)
          )
          waterMaterial.backFaceCulling = true
          //设置水面的纹理贴图
          waterMaterial.bumpTexture = new Texture(
            '/src/assets/textures/waterbump.png',
            scene
          )
          waterMaterial.bumpHeight = 0.5 // 纹理凹凸强度
          //设置风力,决定了水波运动速度
          waterMaterial.windForce = -40
          //设置风向x
          waterMaterial.windDirection.x = 0.2
          //设置风向y
          waterMaterial.windDirection.y = 0.3
          //设置水的波浪高度
          waterMaterial.waveHeight = 0.01
          //设置水纹理高度
          waterMaterial.bumpHeight = 0.2
          //设置波浪的长度
          waterMaterial.waveLength = 0.2
          //设置波浪运行速度
          waterMaterial.waveSpeed = 100
          //设置水的颜色
          waterMaterial.waterColor = new Color3(0, 0, 221 / 255)
          waterMaterial.alpha = 0.5 // 设置透明度
          // 颜色混合强度
          waterMaterial.colorBlendFactor = 0.1
          waterMaterial.addToRenderList(skybox)
          waterMaterial.addToRenderList(ground)
          groundMesh.material = waterMaterial
          groundMesh.freezeWorldMatrix()
        }
      })
      .catch(() => {})
  }

  // 生成山体
  const createMountain = (scene: Scene) => {
    const moutains = [
      {
        name: 'moutain1',
        position: new Vector3(-100, 0, -120),
        rotation: new Vector3(0, 0, 0),
        scaling: new Vector3(30, 20, 15),
      },
      {
        name: 'moutain2',
        position: new Vector3(-70, 0, -120),
        rotation: new Vector3(0, 0, 0),
        scaling: new Vector3(20, 20, 20),
      },
      {
        name: 'moutain3',
        position: new Vector3(0, 0, -120),
        rotation: new Vector3(0, 0, 0),
        scaling: new Vector3(20, 20, 15),
      },
      {
        name: 'moutain4',
        position: new Vector3(35, 0, -115),
        rotation: new Vector3(0, 0, 0),
        scaling: new Vector3(15, 15, 25),
      },
      {
        name: 'moutain5',
        position: new Vector3(100, 0, -120),
        rotation: new Vector3(0, 0, 0),
        scaling: new Vector3(15, 7.5, 20),
      },
      {
        name: 'moutain6',
        position: new Vector3(80, 0, -115),
        rotation: new Vector3(0, 0, 0),
        scaling: new Vector3(10, 20, 15),
      },
      {
        name: 'moutain7',
        position: new Vector3(60, 0, -120),
        rotation: new Vector3(0, 0, 0),
        scaling: new Vector3(10, 6.25, 15),
      },
    ]
    moutains.map((moutain) => {
      ImportMeshAsync(moutainGlb, scene, {})
        .then((result) => {
          if (result.meshes.length > 0) {
            // 处理加载的网格
            const mesh = result.meshes[1]
            mesh.name = moutain.name
            mesh.position = moutain.position // 设置位置
            mesh.rotation = moutain.rotation // 设置旋转
            mesh.scaling = moutain.scaling // 设置缩放
            const meshMaterial = new StandardMaterial("meshMaterial", scene);
            meshMaterial.diffuseColor = new Color3(82 / 255, 230 / 255, 250 / 255); // 设置颜色
            // const meshMaterial = new GradientMaterial('meshMaterial', scene)
            // meshMaterial.topColor = new Color3(76 / 255, 210 / 255, 240 / 255)
            // meshMaterial.bottomColor = new Color3(
            //   82 / 255,
            //   230 / 255,
            //   250 / 255
            // )
            // meshMaterial.offset = 0.1
            // meshMaterial.alpha=0.1
            // meshMaterial.diffuseTexture = new Texture(moutainTree, scene); // 设置纹理
            meshMaterial.specularColor = new Color3(0.1, 0.1, 0.1); // 设置镜面反射颜色,完全禁用高光
            mesh.material = meshMaterial // 应用材质
            mesh.freezeWorldMatrix()
          }
        })
        .catch(() => {})
    })
  }
</script>

<style scoped>
  canvas {
    width: 100%;
    height: 100%;
    position: absolute;
    top: 0;
    left: 0;
    background: transparent;
  }
</style>
